package com.innerchic.mapper.tpool;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * ================================================
 * 作    者：贾恒飞 >>> 17515250730@163.com
 * 项    目：young
 * 日    期：2021/11/4 14:54
 * 包    名：com.innerchic.mapper.tpool
 * 描    述：线程代理
 * Create by zFox from AndroidStudio4.2
 * ================================================
 */
public class ThreadProxy implements ThreadPoolNorm {

    private ThreadPoolExecutor mExecutor;
    private final int mCorePoolSize;
    private final int mMaximumPoolSize;

    /**
     * 线程池任务执行队列
     */
    private final BlockingQueue<Runnable> workQueue = new LinkedBlockingDeque<>();

    /**
     * 构造方法
     *
     * @param mCorePoolSize    核心池的大小
     * @param mMaximumPoolSize 最大线程数
     */
    public ThreadProxy(int mCorePoolSize, int mMaximumPoolSize) {
        this.mCorePoolSize = mCorePoolSize;
        this.mMaximumPoolSize = mMaximumPoolSize;
    }

    /**
     * 初始化ThreadPoolExecutor
     */
    private void initThreadPoolExecutor() {
        if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
            synchronized (ThreadProxy.class) {
                if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
                    long keepAliveTime = 3000;
                    TimeUnit unit = TimeUnit.MILLISECONDS;
                    ThreadFactory threadFactory = Executors.defaultThreadFactory();
                    RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
                    mExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, keepAliveTime, unit, workQueue,
                            threadFactory, handler);
                }
            }
        }
    }

    /**
     * 执行任务
     */
    @Override
    public void execute(Runnable task) {
        initThreadPoolExecutor();
        mExecutor.execute(task);
    }

    /**
     * 提交任务
     */
    @Override
    public Future<?> submit(Runnable task) {
        initThreadPoolExecutor();
        return mExecutor.submit(task);
    }

    /**
     * 阻塞方法
     *
     * @return 获取到对象时任务结束, 如果抛出对象为异常对象, 则证明执行任务时出现了异常
     */
    @Override
    public Object executeWait(Runnable task) {
        initThreadPoolExecutor();
        Future<?> submit = mExecutor.submit(task);
        try {
            return submit.get();
        } catch (Exception e) {
            return e;
        }
    }

    /**
     * 移除任务
     */
    @Override
    public void remove(Runnable task) {
        initThreadPoolExecutor();
        mExecutor.remove(task);
    }

    /**
     * 拿到当前代理进程的线程池队列
     *
     * @return 队列集合
     */
    public BlockingQueue<Runnable> getWorkQueue() {
        return workQueue;
    }

}
